package io.ede.common.utils;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

public class ZipUtils {

    /**
     * 解压压缩文件流，并根据解压层次来判断，是否只解析第一层，还是解析所有数据
     * map<name,inputstream>
     * @param in
     * @return
     */
    public static Map<String,Object> unZip(InputStream in) {
        if (in == null) {
            return null;
        }
        ZipEntry zipEntry = null;
        FileOutputStream out = null;
        Map<String, Object> map = new HashMap<String, Object>();
        ZipInputStream zipIn = new ZipInputStream(in, Charset.forName("GBK"));
        try {
            while ((zipEntry = zipIn.getNextEntry()) != null) {
                //如果是文件夹路径方式，本方法内暂时不提供操作
                if (zipEntry.isDirectory()) {
                    //String name = zipEntry.getName();
                    //name = name.substring(0, name.length() - 1);
                    //File file = new File(outputDirectory + File.separator + name);
                    //file.mkdir();
                } else {
                    //如果是文件，则直接存放在Map中
                    String name = zipEntry.getName();
                    //把压缩文件内的流转化为字节数组，够外部逻辑使用(之后关闭流)
                    byte[] bt = IOUtils.toByteArray(zipIn);
                    map.put(name, bt);
                }
            }
            return map;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        } finally {
            IOUtils.closeQuietly(zipIn);
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
        }
    }

    /**
     * 获取指定字符串出现的次数
     *
     * @param srcText 源字符串
     * @param findText 要查找的字符串
     * @return
     */
    public static int appearNumber(String srcText, String findText) {
        int count = 0;
        Pattern p = Pattern.compile(findText);
        Matcher m = p.matcher(srcText);
        while (m.find()) {
            count++;
        }
        return count;
    }

    private static void zipFile(ZipOutputStream zipOutputStream, File file, String parentFileName){
        FileInputStream in = null;
        try {
            ZipEntry zipEntry = new ZipEntry( parentFileName);
            zipOutputStream.putNextEntry( zipEntry );
            in = new FileInputStream( file);
            int len;
            byte [] buf = new byte[8*1024];
            while ((len = in.read(buf)) != -1){
                zipOutputStream.write(buf, 0, len);
            }
            zipOutputStream.closeEntry(  );
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 递归压缩目录结构
     * @param zipOutputStream
     * @param file
     * @param parentFileName
     */
    private static void directory(ZipOutputStream zipOutputStream,File file,String parentFileName){
        File[] files = file.listFiles();
        String parentFileNameTemp = null;
        for (File fileTemp: files) {
            parentFileNameTemp =  StringUtils.isEmpty(parentFileName)?fileTemp.getName():parentFileName+"/"+fileTemp.getName();
            if(fileTemp.isDirectory()){
                directory(zipOutputStream,fileTemp, parentFileNameTemp);
            }else{
                zipFile(zipOutputStream,fileTemp,parentFileNameTemp);
            }
        }
    }

    /**
     * 压缩文件目录
     * @param source 源文件目录（单个文件和多层目录）
     * @param destit 目标目录
     */
    public static void zipFiles(String source,String destit) {
        File file = new File( source );
        ZipOutputStream zipOutputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream( destit );
            zipOutputStream = new ZipOutputStream( fileOutputStream );
            if (file.isDirectory()) {
                directory( zipOutputStream, file, "" );
            } else {
                zipFile( zipOutputStream, file, "" );
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                zipOutputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ZipUtils.zipFiles( "D:\\系统开发\\3. 歌儿无人机\\code\\project\\1\\test" ,"D:\\系统开发\\3. 歌儿无人机\\code\\project\\1\\test.zip");
    }

    /*public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream(new File("D:\\系统开发\\3. 歌儿无人机\\资料\\4机海草舞F400.zip"));
        Map map = unZip(in);

        SortedMap<String,Object> sortedMapPy = new TreeMap<String,Object>();
        SortedMap<String,Object> sortedMapXml = new TreeMap<String,Object>();

        for(Object keyObj: map.keySet()) {
            String key = keyObj.toString();
            byte[] value = (byte[]) map.get(keyObj);
            //System.out.println("key:" + key + " vlaue:" + value);
            //读取工程名称
            if (key.contains(".fii") && appearNumber(key, "/") == 1) {
                String[] projectNames = key.split("/");
                System.out.println("工程名称：" + projectNames[0]);
                System.out.println("fii文件内容：" + new String(value));
            }
            //读取工作组py文件
            if (key.contains("webCodeAll.py") && key.contains("动作组") && appearNumber(key, "/") == 3) {
                //System.out.println("文件名：" + key);
                //System.out.println("文件内容：" + new String(value));
                sortedMapPy.put(key,new String(value));
            }
            //读取工作组xml文件
            if (key.contains("webCodeAll.xml") && key.contains("动作组") && appearNumber(key, "/") == 3) {
                //System.out.println("文件名：" + key);
                //System.out.println("文件内容：" + new String(value));
                sortedMapXml.put(key,new String(value));
            }
        }

        for(String key:sortedMapPy.keySet()) {
            System.out.println("文件名：" + key);
        }

        for(String key:sortedMapXml.keySet()) {
            System.out.println("文件名：" + key);
        }

    }*/


}
